﻿using System.Linq;

using SeriesManager.Control;
using SeriesManager.Enum;
using SeriesManager.Model.Banner;
using SeriesManager.Model.Comparer;

namespace SeriesManager.Model
{
    public sealed class SeasonModel : BindableBase
    {
        #region Properties

        private readonly int id;
        private readonly SeriesModel series;

        private SeasonBannerModel banner;
        private int number;
        private WatchState state = WatchState.Unwatched;

        public EpisodeModel this[int episodeNumber]
        {
            get
            {
                return this.Episodes.FirstOrDefault(E => E.Number == episodeNumber);
            }
        }

        public int ID
        {
            get
            {
                return this.id;
            }
        }

        public SeriesModel Series
        {
            get
            {
                return this.series;
            }
        }

        public SeasonBannerModel Banner
        {
            get 
            { 
                return this.banner; 
            }
            set 
            {
                base.SetProperty(ref this.banner, value);
            }
        }

        public int Number
        {
            get 
            { 
                return this.number; 
            }
            set 
            { 
                base.SetProperty(ref this.number, value); 
            }
        }

        public ObservableSortedList<EpisodeModel> Episodes 
        { 
            get; 
            private set; 
        }

        public ObservableSortedList<EpisodeModel> Watched 
        { 
            get; 
            private set; 
        }

        public ObservableSortedList<EpisodeModel> Unwatched 
        { 
            get; 
            private set; 
        }

        public ObservableSortedList<EpisodeModel> UnAired 
        { 
            get; 
            private set; 
        }

        public WatchState State
        {
            get 
            { 
                return this.state; 
            }
            set 
            {
                if (value != WatchState.UnAired)
                {
                    foreach (var episode in this.Episodes)
                    {
                        episode.State = value;
                    }
                }
            }
        }

        #endregion

        #region Contructor

        public SeasonModel(int seasonID, SeriesModel series)
        {
            this.id = seasonID;
            this.series = series;

            this.Watched = new ObservableSortedList<EpisodeModel>(30, new EpisodeComparer());
            this.Watched.CollectionChanged += Watched_CollectionChanged;
            this.Unwatched = new ObservableSortedList<EpisodeModel>(30, new EpisodeComparer());
            this.Unwatched.CollectionChanged += Watched_CollectionChanged;
            this.UnAired = new ObservableSortedList<EpisodeModel>(30, new EpisodeComparer());
            this.UnAired.CollectionChanged += Watched_CollectionChanged;
            this.Episodes = new ObservableSortedList<EpisodeModel>(30, new EpisodeComparer());
        }

        #endregion

        private void Watched_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            if (e.NewItems != null)
            {
                if (!this.Unwatched.Any())
                {
                    var state = this.UnAired.Any() ? WatchState.UnAired : WatchState.Watched;
                    base.SetProperty(ref this.state, state, "State");
                }
                else
                {
                    base.SetProperty(ref this.state, WatchState.Unwatched, "State");
                }
            }
        }
    }
}
